커스텀 이벤트(CustomEvent and EventTarget)
✒️ 2025-05-08 00:08 내용 수정
참고 자료 : mdn web docs CustomEvent, mdn web docs CustomEvent Constructor, mdn web docs Creating and triggering events
사용 계기
- 유투브 클론코딩 팀 프로젝트를 진행하면서
click이나DOMContentLoaded등의 이벤트 외의 다른 이벤트를 사용할 필요가 있었다.- 검색 결과를 표시하는
search.html에는 여러 JavaScript 파일로 출력할 DOM 요소(div등)를 만들어 내용을 구성한다. - 이 때 태그 필터링을 위한 버튼을 만드는 파일 A가 있고, 검색으로 나온 동영상 전체를 출력하는 파일 B가 있다.
- A에서 태그 버튼을 눌렀을 때 B에 태그가 바뀌었다는 것을 알려줄 방법이 필요하다.
- 검색 결과를 표시하는
- 두 파일을 포함하는
search.html에서 공용으로 사용할 JavaScript 파일에서 전역 변수를 지정할지 고민했으나, 해당 변수를export및import로 관리해야 할 것 같아 관리 측면에서 어려울 것 같았다. - 따라서 A 파일에서 변화가 일어나면 B에서 변화를 감지할 방법이 필요했고, ChatGPT에 아이디어를 검색한 결과 커스텀 이벤트를 만드는 방법을 찾게 되었다.
생성자
new CustomEvent()를 사용하여 커스텀 이벤트 객체를 생성한다.eventType: 이벤트 이름이며, 이벤트 이름은 대소문자를 구별한다.options: 이벤트의 속성을 설정할 수 있다.detail: 이벤트에 의존하는 값을 지정한다.CustomEvent.detail속성으로 사용할 수 있다.
new CustomEvnet(eventType);
new CustomEvnet(eventType, options);
// 태그 변수 생성
let tag = 'all';
// tag에 관한 커스텀 이벤트 생성
const event = new CustomEvent("tagChanged", {detail: tag});
이벤트 전송(EventTarget object)
참고 자료 : mdn web docs EventTarget, mdn web docs dispatchEvent
EventTarget: 이벤트를 받을 수 있고 리스너를 가질 수 있는 객체에 의해 구현되는 인터페이스다.Element,Document,window등은 이벤트 타겟이다.
| 메서드 | 설명 |
|---|---|
EventTarget.addEventListener() |
EventTarget에 특정 이벤트 타입의 핸들러를 등록 |
EventTarget.removeEventListener() |
EventTarget에 등록된 이벤트 핸들러를 제거 |
EventTarget.dispatchEvent() |
이벤트를 해당 EventTarget에 보냄 |
// 태그 변수 생성
let tag = 'all';
// tag에 관한 커스텀 이벤트 생성
const event = new CustomEvent("tagChanged", {detail: tag});
// 이벤트를 감지할 요소 생성
const container = document.createElement("div");
// event target에 커스텀 이벤트 전송
container.dispatchEvent(event);
적용 예시
- 예시는 프로젝트에 적용한 내용을 간략하게 수정하였다.
- 태그 변수를 저장할
tag_filter.js을 생성하고, 이 파일에선 태그 변수 선언과 태그를 지정하는setTag(), 태그를 불러오는getTag()메서드를 정의한다.setTag()와getTag()를 사용하여tag에 직접 접근하지 않고 메서드를 통해 접근하도록 설정했다.- JavaScript의 변수이므로 브라우저를 새로고침하면
tag는 다시 초기값으로 설정된다.
setTag()메서드에서 새 태그를 지정할 때document요소에CustomEvent인tagChanged이벤트를 전송하도록 작성했다.setTag()와getTag()만export로 내보낸다.
// tag_filter.js
// 홈, 검색 페이지의 태그 관리 js
let tag = '전체';
// 태그 새로 지정
export function setTag(newTag) {
tag = newTag;
// 커스텀 이벤트 지정
document.dispatchEvent(new CustomEvent('tagChanged', {detail: tag}));
}
// 태그 가져오기
export function getTag() {
return tag;
}
- 태그 버튼을 만드는 JavaScript에서
tag_filter.js의setTag()를 가져온다. document에 등록된<button class="tag_button">요소들을 가져오고, 버튼에click이벤트 리스너를 등록한다.- 버튼 클릭 시 버튼 내의 텍스트를
tag_filter.js에 있는tag에 저장하도록setTag()를 호출한다.
- 버튼 클릭 시 버튼 내의 텍스트를
// button_list.js
import { setTag } from "./tag_filter.js";
const item_buttons = document.querySelectorAll(".tag_button");
// 버튼 배열에 동작 수행
item_buttons.forEach(btn => {
// 버튼에 클릭 이벤트 리스너 등록
btn.addEventListener("click", (e)=>{
// 선택한 버튼의 태그 내용을 tag 변수에 저장
setTag(e.target.textContent);
});
});
- 이벤트 변화를 감지할
search.js에서tag_filter.js의getTag()메서드를 가져온다. tag_filter()에서document가CustomEvent를 받는 대상이므로,document에tagChanged이벤트 리스너를 등록한다.getTag()로 현재 태그 내용을 가져와 콘솔로 출력한다.
// search.js
import { getTag } from "./tag_filter.js";
// 태그가 바뀌는 이벤트를 받으면 수행할 내용을 등록
document.addEventListener('tagChanged', function () {
// 버튼으로 설정된 태그 가져오기
const tag_filter = getTag();
// 태그 확인
console.log(tag_filter);
});